package com.sky.service.courier.impl;

import cn.hutool.core.util.StrUtil;
import com.sky.dto.UserLoginDTO;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.admin.MerchantMapper;
import com.sky.mapper.courier.CourierMapper;
import com.sky.mapper.courier.CourierTradeOrderMapper;
import com.sky.pojo.Courier;
import com.sky.pojo.CourierTradeOrder;
import com.sky.pojo.Merchant;
import com.sky.service.courier.CourierService;
import com.sky.utils.MapUtils;
import com.sky.vo.CourierTradeOrderDetailItemVO;
import com.sky.vo.CourierTradeOrderDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description CourierServiceImpl
 * @Author lyh
 * @Date 2024-10-21
 */
@Service
public class CourierServiceImpl implements CourierService {
    @Autowired
    private CourierMapper courierMapper;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CourierTradeOrderMapper courierTradeOrderMapper;
    /*@Override
    public List<Courier> findCourierNearMerchant(Long shopId) {
        //找出所有在职的骑手
        List<Courier> courierList= courierMapper.findAllOnJob();
        Merchant merchant = merchantMapper.selectById(shopId);
        if(merchant==null){
            throw new OrderBusinessException("该商家不存在");
        }
        String shopGao = MapUtils.addressToLnglat(merchant.getShopAddress());
       //筛选出距商家十公里以内的骑手
        courierList=courierList.stream().filter(courier -> {
            double distance = MapUtils.calculateDistance(shopGao, courier.getCurLocation());
            System.out.println(distance+"----------"+courier.getId());
            return distance<10000;
        }).collect(Collectors.toList());
        return courierList;
    }*/

    @Override
    public List<Courier> findCourierNearMerchant(Long shopId) {

        Merchant merchant = merchantMapper.selectById(shopId);
        //116.310442,40.056564
        String shopGeo = MapUtils.addressToLnglat(merchant.getShopAddress());
        String[] lnglat = shopGeo.split(",");
        // 以经纬度为中心，获取半径不超过最大距离的所有元素
        Point point = new Point(Double.parseDouble(lnglat[0]),Double.parseDouble(lnglat[1]));
        // 半径为80km
        Distance distance = new Distance(10, RedisGeoCommands.DistanceUnit.KILOMETERS);
        Circle circle = new Circle(point, distance);

        List<Long> courierIds = new ArrayList<>();
        GeoResults<RedisGeoCommands.GeoLocation<Object>> results = redisTemplate.opsForGeo().radius("location2",circle);
        List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> content = results.getContent();
        for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult:content){
            RedisGeoCommands.GeoLocation<Object> geoResultContent = geoResult.getContent();
            System.out.println("名字:"+geoResultContent.getName());

            String idStr = geoResultContent.getName().toString().split("_")[1];
            courierIds.add(Long.parseLong(idStr));
        }

        //根据骑手的id查询骑手信息
        List<Courier> courierList = courierMapper.findCourierByIds(courierIds);

        //  return courierList;
        return courierList;
    }

    @Override
    public Courier login(UserLoginDTO dto) {
        if(dto==null){
            throw new RuntimeException("登录信息不能为空");
        }
        if(StrUtil.isEmpty(dto.getTelephone())||StrUtil.isEmpty(dto.getCode())){
            throw new RuntimeException("登录信息不正确");
        }
        String key="code:"+dto.getTelephone();
        String code = redisTemplate.opsForValue().get(key).toString();
        if(code==null){
            throw new RuntimeException("验证码过期请重新获取");
        }
        Courier courier=courierMapper.getCourierByTel(dto.getTelephone());
        if(courier==null){
            throw new RuntimeException("登录信息不正确");
        }
        return courier;
    }

    @Override
    public Courier findById(Long id) {
        return courierMapper.getById(Math.toIntExact(id));
    }

    /**
     * 骑手的月度统计
     * @param courierId
     * @param date
     * @return
     */
    @Override
    public CourierTradeOrderDetailVO findCourierMonthTradeOrderInfo(Long courierId, String date) {
        Integer month = Integer.valueOf(date.split("-")[1]);
        //获取月的第一天
        String firstDayOfMonth = getFirstDayOfMonth(month);
        String start=firstDayOfMonth+" 00:00:00";
        //获取月的最后一天
        String lastDayOfMonth = getLastDayOfMonth(month);
        String end=lastDayOfMonth+" 23:59:59";
        // 3.当月完成的订单量
        Long complateCount= courierTradeOrderMapper.selectMonthComplated(start,end,courierId, CourierTradeOrder.TRADE_COMPLETE);
        //4.当月取消的订单量
        Long cancelCount= courierTradeOrderMapper.selectMonthComplated(start,end,courierId, CourierTradeOrder.CANCLE_TRADE);
        //4.当月按时完成的订单
       Long onTimeCount= courierTradeOrderMapper.selectMonthComplateOnTime(start,end,courierId, CourierTradeOrder.TRADE_COMPLETE);
//        1.配送准时订单率 = 按时配送完成的订单/所有配送完成的订单
        Double  tradOrderOnTimeRate=onTimeCount*1.0/complateCount;
//        2.当月订单平均配送时长 时间单位分钟
        Double tradeOrderAverageDuration= courierTradeOrderMapper.countAvgTradeTime(start,end,courierId);

//        5.当月每天的订单完成量和每天的取消量
        LocalDate begin = LocalDate.parse(firstDayOfMonth);
        LocalDate last = LocalDate.parse(lastDayOfMonth);
        List<String> dateList=new ArrayList<>();
        while(!begin.isAfter(last)){
            dateList.add(begin.toString());
            begin=begin.plusDays(1);
        }
        //同济每日完成的数量
        Map<String,Long> comMap =courierTradeOrderMapper.selectDayComOrCan(dateList,start,end,courierId, CourierTradeOrder.TRADE_COMPLETE);
        //统计每日取消的数量
        Map<String,Long> canMap =courierTradeOrderMapper.selectDayComOrCan(dateList,start,end,courierId, CourierTradeOrder.CANCLE_TRADE);
        List<CourierTradeOrderDetailItemVO> list = new ArrayList<>();
        for (String dateStr : dateList) {
            Long canCount = canMap.get(dateStr);
            Long comCount = comMap.get(dateStr);
            CourierTradeOrderDetailItemVO itemVO = CourierTradeOrderDetailItemVO.builder()
                    .tradeOrderDate(dateStr)  //日期
                    .tradeOrdersCancelled(Math.toIntExact(canCount)) //订单取消数
                    .tradeOrdersCompleted(Math.toIntExact(comCount)) //订单完成数
                    .build();
            list.add(itemVO);
        }

        return CourierTradeOrderDetailVO.builder()
                .tradeOrdersCancelled(Math.toIntExact(cancelCount))
                .tradeOrdersCompleted(Math.toIntExact(complateCount))
                .tradeOrderAverageDuration(tradeOrderAverageDuration)
                .tradOrderOnTimeRate(tradOrderOnTimeRate)
                .tradeOrderDetails(list)
                .build();
    }


    /**
     * 获取当前月第一天
     * @param month
     * @return
     */
    public String getFirstDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最小天数
        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        // 设置日历中月份的最小天数
        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String firstDayDate = sdf.format(calendar.getTime());
        return firstDayDate;

    }
    /**
     * 获取当前月最后一天
     * @param month
     * @return
     */
    public String getLastDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay=0;
        //2月的平年瑞年天数
        if(month==2) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayDate = sdf.format(calendar.getTime());
        return lastDayDate;

    }
}
